{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "X6-q-gTUaZU7",
    "tags": []
   },
   "source": [
    "# 第三章 RAG应用评估指标"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 一、介绍\n",
    "本章节主要内容为评估 RAG 应用中常用的三个指标，分别为：\n",
    "1. Answer relevance：评估RAG系统的输出是否与问题相关；\n",
    "2. Context relevance：评估RAG系统召回的上下文是否与问题相关；\n",
    "3. Groundness: 评估RAG系统的输出是否基于召回的上下文；\n",
    "\n",
    "<img src=\"./images/ch03_traid.jpg\" width=\"500\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先需要安装本课程中需要的评估框架，如果已经安装就可以跳过这一步骤。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# requirements\n",
    "# pip install trulens_eval"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在这里，为了美观和方便展示，我们设置输出忽略警告信息。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "height": 47
   },
   "outputs": [],
   "source": [
    "# 忽略警告，避免警告影响输出结果\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，导入该课程需要的工具包utils，然后设置openai的API密钥。\n",
    "有三种方式设置API密钥：\n",
    "1. 在环境变量中设置`OPENAI_API_KEY`，然后使用utils直接获取；\n",
    "2. 显式设置api_key，直接赋值给openai.api_key；\n",
    "3. 如果没有openai的密钥的话，也可以选择使用第三方服务，修改openai.api_base即可；"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "height": 98
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ In Answer Relevance, input prompt will be set to __record__.main_input or `Select.RecordInput` .\n",
      "✅ In Answer Relevance, input response will be set to __record__.main_output or `Select.RecordOutput` .\n",
      "✅ In Context Relevance, input prompt will be set to __record__.main_input or `Select.RecordInput` .\n",
      "✅ In Context Relevance, input response will be set to __record__.app.query.rets.source_nodes[:].node.text .\n",
      "✅ In Groundedness, input source will be set to __record__.app.query.rets.source_nodes[:].node.text .\n",
      "✅ In Groundedness, input statement will be set to __record__.main_output or `Select.RecordOutput` .\n"
     ]
    }
   ],
   "source": [
    "import utils\n",
    "# 导入自定义的工具包\n",
    "\n",
    "import os\n",
    "import openai\n",
    "# openai.api_key = utils.get_openai_api_key()\n",
    "# 设置OpenAI的API密钥，从环境变量中获取\n",
    "\n",
    "# openai.api_key = \"\" \n",
    "# 或者这里填入你的OpenAI API密钥\n",
    "\n",
    "# openai.api_key = \"sk- \"  \n",
    "# openai.api_base = \" \"\n",
    "# 或者自定义API密钥和API基础地址，可适用第三方API服务\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接来下，开始教程的设置环节。\n",
    "首先需要重置数据库，这会在之后用于存储问题、召回结果和回答，方便管理和评估。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "height": 81,
    "id": "IBfdyn3MaZU9"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "🦑 Tru initialized with db url sqlite:///default.sqlite .\n",
      "🛑 Secret keys may be written to the database. See the `database_redact_keys` option of `Tru` to prevent this.\n"
     ]
    }
   ],
   "source": [
    "# 导入Tru类\n",
    "from trulens_eval import Tru\n",
    "\n",
    "\n",
    "# 实例化Tru类\n",
    "tru = Tru()\n",
    "\n",
    "# 重置数据库\n",
    "# 数据库之后会用来存储问题、中间召回结果、答案以及评估结果\n",
    "tru.reset_database()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，导入读取pdf所需要的SimpleDirectoryReader，读取指定文件夹下的pdf文件。\n",
    "需要注意的是，默认的参数适合读取英文文档，如果文档为中文，需要在后续将全角字符转换为半角字符。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "height": 98,
    "id": "wMvq1q8yaZU-"
   },
   "outputs": [],
   "source": [
    "# 设置Llama Index reader\n",
    "from llama_index import SimpleDirectoryReader\n",
    "\n",
    "# 从一个文件夹中读取PDF文档，然后加载到document对象中\n",
    "# 使用的文档为“人工智能”词条的维基百科页面\n",
    "documents = SimpleDirectoryReader(\n",
    "    input_files=[\"./data/人工智能.pdf\"]\n",
    ").load_data()\n",
    "\n",
    "documents_en = SimpleDirectoryReader(\n",
    "    input_files=[\"./data/eBook-How-to-Build-a-Career-in-AI.pdf\"]\n",
    ").load_data()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "为了方面起见，将读取的pdf文档加载到同一个document对象中，用`\"\\n\\n\"`隔开；"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "height": 81,
    "id": "sY8Oui4taZU-"
   },
   "outputs": [],
   "source": [
    "from llama_index import Document\n",
    "\n",
    "# 将documents中的内容合并成一个大文档，而不是每一页都是一个文档\n",
    "document = Document(text=\"\\n\\n\".\\\n",
    "                    join([doc.text for doc in documents]))\n",
    "\n",
    "document_en = Document(text=\"\\n\\n\".\\\n",
    "                    join([doc.text for doc in documents_en]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 将中文标点符号替换成英文标点符号，方便后续处理\n",
    "# 如果是英文文档，可以跳过这一步\n",
    "# 不处理的话，会导致无法正确切分中文句子，会影响后续sentence_window的大小，导致输入长度大于gpt-3.5-turbo的最大限制\n",
    "document.text=document.text.replace('。','. ')\n",
    "document.text=document.text.replace('！','! ')\n",
    "document.text=document.text.replace('？','? ')\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "设置index存储，首先设置用来评估的大模型为gpt-3.5-turbo，需要注意的是这里使用的版本的上下文窗口为4096，因此需要注意输入的长度。\n",
    "然后设置embedding模型，我们选择了BAAI/bge-small-zh-v1.5，这里可以根据场景的需要和计算资源的trade off选择模型的大小和语种。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "height": 217
   },
   "outputs": [],
   "source": [
    "# 设置sentence_index\n",
    "from utils import build_sentence_window_index\n",
    "\n",
    "from llama_index.llms import OpenAI\n",
    "\n",
    "# 设置使用的大模型\n",
    "# \"gpt-3.5-turbo\"是模型的名称\n",
    "# temperature是温度，用来控制文本生成过程中的多样性\n",
    "llm = OpenAI(model=\"gpt-3.5-turbo\", temperature=0.1)\n",
    "\n",
    "# 设置embedding模型\n",
    "# 这里是在本地使用BAAI/bge-small-zh-v1.5\n",
    "# document的所有的内容会索引到sentence index对象中\n",
    "# 国内使用可以切换huggingface镜像站\n",
    "sentence_index = build_sentence_window_index(\n",
    "    document,\n",
    "    llm,\n",
    "    embed_model=\"local:BAAI/bge-small-zh-v1.5\",\n",
    "    save_dir=\"sentence_index\"\n",
    ")\n",
    "\n",
    "sentence_index_en = build_sentence_window_index(\n",
    "    document_en,\n",
    "    llm,\n",
    "    embed_model=\"local:BAAI/bge-small-en-v1.5\",\n",
    "    save_dir=\"sentence_index_en\"\n",
    ")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用工具包中封装好的函数，基于上一步建立好的索引，返回用于之后检索的引擎。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "height": 81
   },
   "outputs": [],
   "source": [
    "from utils import get_sentence_window_query_engine\n",
    "\n",
    "# 根据sentence_index对象创建一个搜索引擎\n",
    "# 之后会被用于在RAG应用中进行召回\n",
    "sentence_window_engine = \\\n",
    "get_sentence_window_query_engine(sentence_index)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "sentence_window_engine_en = \\\n",
    "get_sentence_window_query_engine(sentence_index_en)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里我们先测试单个问题来debug，看一下输出是什么。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "height": 64
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n",
      "To disable this warning, you can either:\n",
      "\t- Avoid using `tokenizers` before the fork if possible\n",
      "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n"
     ]
    }
   ],
   "source": [
    "output = sentence_window_engine.query(\n",
    "    \"AI的核心问题和长远目标是什么？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "output_en = sentence_window_engine_en.query(\n",
    "    \"How do you create your AI portfolio?\")\n",
    "# 示例：使用搜索引擎进行召回"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'7e8484a0-f7d2-4b64-b683-fa76b1dec6fe': {'window': '⼈⼯智能的研究是⾼度技术性和专业的，各分⽀领域都是深⼊且各不相通的，因⽽涉及范围极⼴[9].  ⼈⼯智能的\\n研究可以分为⼏个技术问题.  其分⽀领域主要集中在解决具体问题，其中之⼀是，如何使⽤各种不同的⼯具完成\\n特定的应⽤程序. \\n AI的核⼼问题包括建构能够跟⼈类似甚⾄超卓的推理、知识、计划、学习、交流、感知、移动 、移物、使⽤⼯\\n具和操控机械的能⼒等[10].  通⽤⼈⼯智能（GAI）⽬前仍然是该领域的长远⽬标[11].  ⽬前弱⼈⼯智能已经有初\\n步成果，甚⾄在⼀些影像识别、语⾔分析、棋类游戏等等单⽅⾯的能⼒达到了超越⼈类的⽔平，⽽且⼈⼯智能的\\n通⽤性代表着，能解决上述的问题的是⼀样的AI程序，⽆须重新开发算法就可以直接使⽤现有的AI完成任务，与\\n⼈类的处理能⼒相同，但达到具备思考能⼒的统合强⼈⼯智能还需要时间研究，⽐较流⾏的⽅法包括统计⽅法，\\n计算智能和传统意义的AI. ',\n",
       "  'original_text': 'AI的核⼼问题包括建构能够跟⼈类似甚⾄超卓的推理、知识、计划、学习、交流、感知、移动 、移物、使⽤⼯\\n具和操控机械的能⼒等[10]. '},\n",
       " '4e0b1c3d-5ba5-4c6b-b5c6-29df66a75281': {'window': '⼈⼯智能的\\n研究可以分为⼏个技术问题.  其分⽀领域主要集中在解决具体问题，其中之⼀是，如何使⽤各种不同的⼯具完成\\n特定的应⽤程序. \\n AI的核⼼问题包括建构能够跟⼈类似甚⾄超卓的推理、知识、计划、学习、交流、感知、移动 、移物、使⽤⼯\\n具和操控机械的能⼒等[10].  通⽤⼈⼯智能（GAI）⽬前仍然是该领域的长远⽬标[11].  ⽬前弱⼈⼯智能已经有初\\n步成果，甚⾄在⼀些影像识别、语⾔分析、棋类游戏等等单⽅⾯的能⼒达到了超越⼈类的⽔平，⽽且⼈⼯智能的\\n通⽤性代表着，能解决上述的问题的是⼀样的AI程序，⽆须重新开发算法就可以直接使⽤现有的AI完成任务，与\\n⼈类的处理能⼒相同，但达到具备思考能⼒的统合强⼈⼯智能还需要时间研究，⽐较流⾏的⽅法包括统计⽅法，\\n计算智能和传统意义的AI.  ⽬前有⼤量的⼯具应⽤了⼈⼯智能，其中包括搜索和数学优化、逻辑推演. ',\n",
       "  'original_text': '通⽤⼈⼯智能（GAI）⽬前仍然是该领域的长远⽬标[11]. '}}"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 在实际开发中，可以通过查看metadata进行debug\n",
    "output.metadata"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'e0d0633c-9a38-4330-8980-2e4ceea28d30': {'window': 'Chapter 4: Scoping Successful AI Projects.\\n Chapter 5: Finding Projects that Complement \\nYour Career Goals.\\n Chapter 6: Building a Portfolio of Projects that \\nShows Skill Progression.\\n Chapter 7: A Simple Framework for Starting Your AI \\nJob Search.\\n Chapter 8: Using Informational Interviews to Find \\nthe Right Job.\\n Chapter 9: Finding the Right AI Job for You.\\n',\n",
       "  'original_text': 'Chapter 7: A Simple Framework for Starting Your AI \\nJob Search.\\n'},\n",
       " '600b5970-e3cd-47cd-a2e0-ea2ffb2c5e79': {'window': 'Chapter 6: Building a Portfolio of Projects that \\nShows Skill Progression.\\n Chapter 7: A Simple Framework for Starting Your AI \\nJob Search.\\n Chapter 8: Using Informational Interviews to Find \\nthe Right Job.\\n Chapter 9: Finding the Right AI Job for You.\\n Chapter 10: Keys to Building a Career in AI.\\n Chapter 11: Overcoming Imposter Syndrome.\\n',\n",
       "  'original_text': 'Chapter 9: Finding the Right AI Job for You.\\n'}}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "output_en.metadata"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 二、 Feedback functions\n",
    "feedback function是一个衡量RAG系统的问题、上下文、答案三者之间关系的函数。在RAG系统中，feedback function通常是一个评估模型的指标，用于评估RAG系统的各个方面的性能。具体来说，在本教程中，主要为，answer relevance、context relevance、groundness三个指标。\n",
    "\n",
    "<img src=\"./images/ch03_feedback.jpg\" width=\"500\">\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "height": 64,
    "id": "5KqV-IbQaZVB"
   },
   "outputs": [],
   "source": [
    "import nest_asyncio\n",
    "\n",
    "# 保证后续可以使用streamlit进行评估结果管理和可视化\n",
    "nest_asyncio.apply()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "from trulens_eval import OpenAI as fOpenAI\n",
    "\n",
    "# 初始化OpenAI gpt-3.5-turbo模型作为provider\n",
    "# provider之后会用来辅助评估RAG应用的各个指标：answer relevance, context relevance, groundedness.\n",
    "provider = fOpenAI()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.1、 Answer Relevance\n",
    "answer relevance用来评估RAG系统的输出是否与问题相关。\n",
    "\n",
    "<img src=\"./images/ch03_answer_rele.jpg\" width=\"500\">\n",
    "\n",
    "\n",
    "answer relevance的feedback function的结构为：\n",
    "\n",
    "<img src=\"./images/ch03_structure_answer.jpg\" width=\"500\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里使用封装好的Feedback函数即可，我们需要做的是：指定评估的方式，指定名称，以及评估的对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "height": 115
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ In Answer Relevance, input prompt will be set to __record__.main_input or `Select.RecordInput` .\n",
      "✅ In Answer Relevance, input response will be set to __record__.main_output or `Select.RecordOutput` .\n"
     ]
    }
   ],
   "source": [
    "from trulens_eval import Feedback\n",
    "\n",
    "\n",
    "# 这里为answer relevance设置feedback\n",
    "# 使用provider.relevance_with_cot_reasons作为评估函数，即，通过调用LLM使用chain of thought的方式进行评估\n",
    "# on_input_output()表示在输入和输出上进行评估\n",
    "f_qa_relevance = Feedback(\n",
    "    provider.relevance_with_cot_reasons,\n",
    "    name=\"Answer Relevance\"\n",
    ").on_input_output()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.2、 Context Relevance\n",
    "context relevance用来评估RAG系统召回的上下文是否与问题相关。\n",
    "\n",
    "<img src=\"./images/ch03_context_rele.jpg\" width=500>\n",
    "\n",
    "其feedback function的结构为：\n",
    "\n",
    "<img src=\"./images/ch03_structure_context.jpg\" width=500>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "from trulens_eval import TruLlama\n",
    "\n",
    "# 选择召回的上下文\n",
    "context_selection = TruLlama.select_source_nodes().node.text"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里的设置和上一步类似，只需要修改评估的对象即可。\n",
    "也可以选择修改评估的方式，进行对比。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "height": 166
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ In Context Relevance, input question will be set to __record__.main_input or `Select.RecordInput` .\n",
      "✅ In Context Relevance, input statement will be set to __record__.app.query.rets.source_nodes[:].node.text .\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "# 使用provider.qs_relevance作为评估函数\n",
    "# on_input()表示在输入上进行评估\n",
    "# on(context_selection)表示在context_selection上进行评估\n",
    "# aggregate(np.mean)表示使用np.mean作为聚合函数\n",
    "# 这里实际的意思是：对于context_selection中的每个句子，都会进行评估，然后取平均值作为最终的评估结果\n",
    "f_qs_relevance = (\n",
    "    Feedback(provider.qs_relevance,\n",
    "             name=\"Context Relevance\")\n",
    "    .on_input()\n",
    "    .on(context_selection)\n",
    "    .aggregate(np.mean)\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "height": 166
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ In Context Relevance, input question will be set to __record__.main_input or `Select.RecordInput` .\n",
      "✅ In Context Relevance, input statement will be set to __record__.app.query.rets.source_nodes[:].node.text .\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "# 同上，对于context_selection中的每个句子进行评估，取平均值作为评估结果\n",
    "f_qs_relevance = (\n",
    "    Feedback(provider.qs_relevance_with_cot_reasons,\n",
    "             name=\"Context Relevance\")\n",
    "    .on_input()\n",
    "    .on(context_selection)\n",
    "    .aggregate(np.mean)\n",
    ")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3、 Groundedness"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "height": 64
   },
   "outputs": [],
   "source": [
    "from trulens_eval.feedback import Groundedness\n",
    "\n",
    "grounded = Groundedness(groundedness_provider=provider)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后是groundedness，用来评估RAG系统的输出是否基于召回的上下文。\n",
    "设置和之前的类似。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "height": 149,
    "id": "kXJBD4gfaZVC"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ In Groundedness, input source will be set to __record__.app.query.rets.source_nodes[:].node.text .\n",
      "✅ In Groundedness, input statement will be set to __record__.main_output or `Select.RecordOutput` .\n"
     ]
    }
   ],
   "source": [
    "# groundedness的评估，解释同answer relevance和context relevance\n",
    "f_groundedness = (\n",
    "    Feedback(grounded.groundedness_measure_with_cot_reasons,\n",
    "             name=\"Groundedness\"\n",
    "            )\n",
    "    .on(context_selection)\n",
    "    .on_output()\n",
    "    .aggregate(grounded.grounded_statements_aggregator)\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 三、Evaluation of the RAG application\n",
    "\n",
    "在RAG系统的评估中，feedback function可以通过多种方式实现。\n",
    "使用人工打分的方法可以获得最准确的评估结果，但是这种方法成本较高，因此在实际应用中，通常使用自动评估的方法。\n",
    "在本教程中，使用gpt-3.5-turbo来对RAG系统进行评估。\n",
    "这种方法的好处是，可以快速、低成本地对RAG系统进行评估，但是其评估结果可能不如人工打分准确。\n",
    "\n",
    "<img src=\"./images/ch03_bench.jpg\" width=\"500\">\n",
    "\n",
    "下面是整个RAG系统的评估流程的实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "height": 217,
    "id": "KUDHInR-aZVC"
   },
   "outputs": [],
   "source": [
    "from trulens_eval import TruLlama\n",
    "from trulens_eval import FeedbackMode\n",
    "\n",
    "\n",
    "# 实例化TruLlama类，用来记录评估结果\n",
    "# sentence_window_engine是之前创建的搜索引擎\n",
    "# app_id是应用的ID，用来标识应用\n",
    "tru_recorder = TruLlama(\n",
    "    sentence_window_engine,\n",
    "    app_id=\"App_1\",\n",
    "    feedbacks=[\n",
    "        f_qa_relevance,\n",
    "        f_qs_relevance,\n",
    "        f_groundedness\n",
    "    ]\n",
    ")\n",
    "\n",
    "tru_recorder_en = TruLlama(\n",
    "    sentence_window_engine_en,\n",
    "    app_id=\"App_2\",\n",
    "    feedbacks=[\n",
    "        f_qa_relevance,\n",
    "        f_qs_relevance,\n",
    "        f_groundedness\n",
    "    ]\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "读取用来评估的问题，这里为了节约时间并降低调用API的成本，我们只设置了6个问题。\n",
    "在实际场景中，可以手写或通过prompt seed的方法生成更多的问题，覆盖更多的场景。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "height": 115,
    "id": "dsA3ziw1aZVD"
   },
   "outputs": [],
   "source": [
    "eval_questions = []\n",
    "# 读取评估问题，在./data/eval_questions.txt下，可以自定义\n",
    "with open('./data/eval_questions.txt', 'r') as file:\n",
    "    for line in file:\n",
    "        item = line.strip()\n",
    "        eval_questions.append(item)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "eval_questions_en = []\n",
    "with open('./data/eval_questions_en.txt', 'r') as file:\n",
    "    for line in file:\n",
    "        item = line.strip()\n",
    "        eval_questions_en.append(item)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "height": 30
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['人工智能中的先验知识是如何被存储的？',\n",
       " '人工智能的自我更新和自我提升是否可能导致其脱离人类的控制？',\n",
       " '管理者如何管理AI？',\n",
       " '强人工智能是什么？',\n",
       " '人工智能被滥用带来的危害？']"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eval_questions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['What are the keys to building a career in AI?',\n",
       " \"How can teamwork contribute to success in AI?'\",\n",
       " \"What is the importance of networking in AI?'\",\n",
       " \"What are some good habits to develop for a successful career?'\",\n",
       " \"How can altruism be beneficial in building a career?'\",\n",
       " \"What is imposter syndrome and how does it relate to AI?'\",\n",
       " \"Who are some accomplished individuals who have experienced imposter syndrome?'\",\n",
       " \"What is the first step to becoming good at AI?'\",\n",
       " \"What are some common challenges in AI?'\",\n",
       " 'Is it normal to find parts of AI challenging?']"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eval_questions_en"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "height": 30
   },
   "outputs": [],
   "source": [
    "eval_questions.append(\"如何在人工智能领域获得成功？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "height": 30
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['人工智能中的先验知识是如何被存储的？',\n",
       " '人工智能的自我更新和自我提升是否可能导致其脱离人类的控制？',\n",
       " '管理者如何管理AI？',\n",
       " '强人工智能是什么？',\n",
       " '人工智能被滥用带来的危害？',\n",
       " '如何在人工智能领域获得成功？']"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "eval_questions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来开始评估，请求RAG系统的输出，然后使用feedback function对输出进行评估。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "height": 64,
    "id": "01_P6TxaaZVD"
   },
   "outputs": [],
   "source": [
    "# 对于每个评估问题，进行评估，并记录结果\n",
    "# 注意：该过程可能会比较耗时，请耐心等待\n",
    "for question in eval_questions:\n",
    "    with tru_recorder as recording:\n",
    "        sentence_window_engine.query(question)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "for question in eval_questions_en:\n",
    "    with tru_recorder_en as recording:\n",
    "        sentence_window_engine_en.query(question)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "之后，需要进行编解码，将评估结果转换为中文可读的形式，方便分析。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "height": 47,
    "id": "sNPhDde6ZArq"
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>app_id</th>\n",
       "      <th>app_json</th>\n",
       "      <th>type</th>\n",
       "      <th>record_id</th>\n",
       "      <th>input</th>\n",
       "      <th>output</th>\n",
       "      <th>tags</th>\n",
       "      <th>record_json</th>\n",
       "      <th>cost_json</th>\n",
       "      <th>perf_json</th>\n",
       "      <th>ts</th>\n",
       "      <th>Answer Relevance</th>\n",
       "      <th>Context Relevance</th>\n",
       "      <th>Groundedness</th>\n",
       "      <th>Answer Relevance_calls</th>\n",
       "      <th>Context Relevance_calls</th>\n",
       "      <th>Groundedness_calls</th>\n",
       "      <th>latency</th>\n",
       "      <th>total_tokens</th>\n",
       "      <th>total_cost</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>App_1</td>\n",
       "      <td>{\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...</td>\n",
       "      <td>RetrieverQueryEngine(llama_index.query_engine....</td>\n",
       "      <td>record_hash_e5a8b3d540d5ceefbfbcfc7ab8b66530</td>\n",
       "      <td>\"人工智能中的先验知识是如何被存储的？\"</td>\n",
       "      <td>\"人工智能中的先验知识是通过某种方式告知机器的知识，可以描述目标、特征、种类及对象之间的关系...</td>\n",
       "      <td>-</td>\n",
       "      <td>{\"record_id\": \"record_hash_e5a8b3d540d5ceefbfb...</td>\n",
       "      <td>{\"n_requests\": 0, \"n_successful_requests\": 0, ...</td>\n",
       "      <td>{\"start_time\": \"2024-03-09T20:29:42.283509\", \"...</td>\n",
       "      <td>2024-03-09T20:29:44.818854</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.85</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>[{'args': {'prompt': '人工智能中的先验知识是如何被存储的？', 're...</td>\n",
       "      <td>[{'args': {'question': '人工智能中的先验知识是如何被存储的？', '...</td>\n",
       "      <td>[{'args': {'source': '知识表⽰是⼈⼯智能领域的核⼼研究问题之⼀，它的⽬...</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>App_1</td>\n",
       "      <td>{\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...</td>\n",
       "      <td>RetrieverQueryEngine(llama_index.query_engine....</td>\n",
       "      <td>record_hash_1606ea1a9ed8d5bbc0eb20da128e0433</td>\n",
       "      <td>\"人工智能的自我更新和自我提升是否可能导致其脱离人类的控制？\"</td>\n",
       "      <td>\"人工智能的自我更新和自我提升可能导致其脱离人类的控制。\"</td>\n",
       "      <td>-</td>\n",
       "      <td>{\"record_id\": \"record_hash_1606ea1a9ed8d5bbc0e...</td>\n",
       "      <td>{\"n_requests\": 0, \"n_successful_requests\": 0, ...</td>\n",
       "      <td>{\"start_time\": \"2024-03-09T20:29:44.919348\", \"...</td>\n",
       "      <td>2024-03-09T20:29:46.465240</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.85</td>\n",
       "      <td>0.666667</td>\n",
       "      <td>[{'args': {'prompt': '人工智能的自我更新和自我提升是否可能导致其脱离人...</td>\n",
       "      <td>[{'args': {'question': '人工智能的自我更新和自我提升是否可能导致其脱...</td>\n",
       "      <td>[{'args': {'source': '⾄少，它本⾝应该有正常的情绪. \n",
       " ⼀个⼈⼯智能...</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>App_1</td>\n",
       "      <td>{\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...</td>\n",
       "      <td>RetrieverQueryEngine(llama_index.query_engine....</td>\n",
       "      <td>record_hash_c4b95535dc5bf0b50a931bbeb7332f16</td>\n",
       "      <td>\"管理者如何管理AI？\"</td>\n",
       "      <td>\"Management should consider adjusting their ro...</td>\n",
       "      <td>-</td>\n",
       "      <td>{\"record_id\": \"record_hash_c4b95535dc5bf0b50a9...</td>\n",
       "      <td>{\"n_requests\": 0, \"n_successful_requests\": 0, ...</td>\n",
       "      <td>{\"start_time\": \"2024-03-09T20:29:46.557848\", \"...</td>\n",
       "      <td>2024-03-09T20:29:48.281784</td>\n",
       "      <td>0.9</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.950000</td>\n",
       "      <td>[{'args': {'prompt': '管理者如何管理AI？', 'response':...</td>\n",
       "      <td>[{'args': {'question': '管理者如何管理AI？', 'statemen...</td>\n",
       "      <td>[{'args': {'source': 'AI逐渐普及后，将会在企业管理中扮演很重要的⾓⾊...</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>App_1</td>\n",
       "      <td>{\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...</td>\n",
       "      <td>RetrieverQueryEngine(llama_index.query_engine....</td>\n",
       "      <td>record_hash_2b91f2a57d165175d58926fd1a2dd22c</td>\n",
       "      <td>\"强人工智能是什么？\"</td>\n",
       "      <td>\"强人工智能是一种观点，认为计算机本身具有思维，而不仅仅是用来模拟人类思维的工具。根据这个观...</td>\n",
       "      <td>-</td>\n",
       "      <td>{\"record_id\": \"record_hash_2b91f2a57d165175d58...</td>\n",
       "      <td>{\"n_requests\": 0, \"n_successful_requests\": 0, ...</td>\n",
       "      <td>{\"start_time\": \"2024-03-09T20:29:48.371499\", \"...</td>\n",
       "      <td>2024-03-09T20:29:50.379916</td>\n",
       "      <td>1.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.500000</td>\n",
       "      <td>[{'args': {'prompt': '强人工智能是什么？', 'response': ...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[{'args': {'source': '强⼈⼯智能可以有两\n",
       "类：\n",
       "⼈类的⼈⼯智能，即机器...</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>App_1</td>\n",
       "      <td>{\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...</td>\n",
       "      <td>RetrieverQueryEngine(llama_index.query_engine....</td>\n",
       "      <td>record_hash_2fb0adc005659d26ec770abae7e96329</td>\n",
       "      <td>\"人工智能被滥用带来的危害？\"</td>\n",
       "      <td>\"The misuse of artificial intelligence can pot...</td>\n",
       "      <td>-</td>\n",
       "      <td>{\"record_id\": \"record_hash_2fb0adc005659d26ec7...</td>\n",
       "      <td>{\"n_requests\": 0, \"n_successful_requests\": 0, ...</td>\n",
       "      <td>{\"start_time\": \"2024-03-09T20:29:50.474544\", \"...</td>\n",
       "      <td>2024-03-09T20:29:53.133885</td>\n",
       "      <td>1.0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>[{'args': {'prompt': '人工智能被滥用带来的危害？', 'respons...</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>2</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  app_id                                           app_json  \\\n",
       "0  App_1  {\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...   \n",
       "1  App_1  {\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...   \n",
       "2  App_1  {\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...   \n",
       "3  App_1  {\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...   \n",
       "4  App_1  {\"tru_class_info\": {\"name\": \"TruLlama\", \"modul...   \n",
       "\n",
       "                                                type  \\\n",
       "0  RetrieverQueryEngine(llama_index.query_engine....   \n",
       "1  RetrieverQueryEngine(llama_index.query_engine....   \n",
       "2  RetrieverQueryEngine(llama_index.query_engine....   \n",
       "3  RetrieverQueryEngine(llama_index.query_engine....   \n",
       "4  RetrieverQueryEngine(llama_index.query_engine....   \n",
       "\n",
       "                                      record_id  \\\n",
       "0  record_hash_e5a8b3d540d5ceefbfbcfc7ab8b66530   \n",
       "1  record_hash_1606ea1a9ed8d5bbc0eb20da128e0433   \n",
       "2  record_hash_c4b95535dc5bf0b50a931bbeb7332f16   \n",
       "3  record_hash_2b91f2a57d165175d58926fd1a2dd22c   \n",
       "4  record_hash_2fb0adc005659d26ec770abae7e96329   \n",
       "\n",
       "                             input  \\\n",
       "0             \"人工智能中的先验知识是如何被存储的？\"   \n",
       "1  \"人工智能的自我更新和自我提升是否可能导致其脱离人类的控制？\"   \n",
       "2                     \"管理者如何管理AI？\"   \n",
       "3                      \"强人工智能是什么？\"   \n",
       "4                  \"人工智能被滥用带来的危害？\"   \n",
       "\n",
       "                                              output tags  \\\n",
       "0  \"人工智能中的先验知识是通过某种方式告知机器的知识，可以描述目标、特征、种类及对象之间的关系...    -   \n",
       "1                      \"人工智能的自我更新和自我提升可能导致其脱离人类的控制。\"    -   \n",
       "2  \"Management should consider adjusting their ro...    -   \n",
       "3  \"强人工智能是一种观点，认为计算机本身具有思维，而不仅仅是用来模拟人类思维的工具。根据这个观...    -   \n",
       "4  \"The misuse of artificial intelligence can pot...    -   \n",
       "\n",
       "                                         record_json  \\\n",
       "0  {\"record_id\": \"record_hash_e5a8b3d540d5ceefbfb...   \n",
       "1  {\"record_id\": \"record_hash_1606ea1a9ed8d5bbc0e...   \n",
       "2  {\"record_id\": \"record_hash_c4b95535dc5bf0b50a9...   \n",
       "3  {\"record_id\": \"record_hash_2b91f2a57d165175d58...   \n",
       "4  {\"record_id\": \"record_hash_2fb0adc005659d26ec7...   \n",
       "\n",
       "                                           cost_json  \\\n",
       "0  {\"n_requests\": 0, \"n_successful_requests\": 0, ...   \n",
       "1  {\"n_requests\": 0, \"n_successful_requests\": 0, ...   \n",
       "2  {\"n_requests\": 0, \"n_successful_requests\": 0, ...   \n",
       "3  {\"n_requests\": 0, \"n_successful_requests\": 0, ...   \n",
       "4  {\"n_requests\": 0, \"n_successful_requests\": 0, ...   \n",
       "\n",
       "                                           perf_json  \\\n",
       "0  {\"start_time\": \"2024-03-09T20:29:42.283509\", \"...   \n",
       "1  {\"start_time\": \"2024-03-09T20:29:44.919348\", \"...   \n",
       "2  {\"start_time\": \"2024-03-09T20:29:46.557848\", \"...   \n",
       "3  {\"start_time\": \"2024-03-09T20:29:48.371499\", \"...   \n",
       "4  {\"start_time\": \"2024-03-09T20:29:50.474544\", \"...   \n",
       "\n",
       "                           ts  Answer Relevance  Context Relevance  \\\n",
       "0  2024-03-09T20:29:44.818854               0.8               0.85   \n",
       "1  2024-03-09T20:29:46.465240               1.0               0.85   \n",
       "2  2024-03-09T20:29:48.281784               0.9               0.60   \n",
       "3  2024-03-09T20:29:50.379916               1.0                NaN   \n",
       "4  2024-03-09T20:29:53.133885               1.0                NaN   \n",
       "\n",
       "   Groundedness                             Answer Relevance_calls  \\\n",
       "0      1.000000  [{'args': {'prompt': '人工智能中的先验知识是如何被存储的？', 're...   \n",
       "1      0.666667  [{'args': {'prompt': '人工智能的自我更新和自我提升是否可能导致其脱离人...   \n",
       "2      0.950000  [{'args': {'prompt': '管理者如何管理AI？', 'response':...   \n",
       "3      0.500000  [{'args': {'prompt': '强人工智能是什么？', 'response': ...   \n",
       "4           NaN  [{'args': {'prompt': '人工智能被滥用带来的危害？', 'respons...   \n",
       "\n",
       "                             Context Relevance_calls  \\\n",
       "0  [{'args': {'question': '人工智能中的先验知识是如何被存储的？', '...   \n",
       "1  [{'args': {'question': '人工智能的自我更新和自我提升是否可能导致其脱...   \n",
       "2  [{'args': {'question': '管理者如何管理AI？', 'statemen...   \n",
       "3                                                NaN   \n",
       "4                                                NaN   \n",
       "\n",
       "                                  Groundedness_calls  latency  total_tokens  \\\n",
       "0  [{'args': {'source': '知识表⽰是⼈⼯智能领域的核⼼研究问题之⼀，它的⽬...        2             0   \n",
       "1  [{'args': {'source': '⾄少，它本⾝应该有正常的情绪. \n",
       " ⼀个⼈⼯智能...        1             0   \n",
       "2  [{'args': {'source': 'AI逐渐普及后，将会在企业管理中扮演很重要的⾓⾊...        1             0   \n",
       "3  [{'args': {'source': '强⼈⼯智能可以有两\n",
       "类：\n",
       "⼈类的⼈⼯智能，即机器...        2             0   \n",
       "4                                                NaN        2             0   \n",
       "\n",
       "   total_cost  \n",
       "0         0.0  \n",
       "1         0.0  \n",
       "2         0.0  \n",
       "3         0.0  \n",
       "4         0.0  "
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "records, feedback = tru.get_records_and_feedback(app_ids=[])\n",
    "\n",
    "# 将记录中的unicode转换成中文，方便查看\n",
    "def decode_unicode(s):\n",
    "    return s.encode('ascii').decode('unicode-escape')\n",
    "\n",
    "records['input'] = records['input'].apply(decode_unicode)\n",
    "records['output'] = records['output'].apply(decode_unicode)\n",
    "\n",
    "records.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "height": 81
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>input</th>\n",
       "      <th>output</th>\n",
       "      <th>Groundedness</th>\n",
       "      <th>Answer Relevance</th>\n",
       "      <th>Context Relevance</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>\"人工智能中的先验知识是如何被存储的？\"</td>\n",
       "      <td>\"人工智能中的先验知识是通过某种方式告知机器的知识，可以描述目标、特征、种类及对象之间的关系，也可以描述事件、时间、状态、原因和结果，以及任何需要机器存储的知识。\"</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.8</td>\n",
       "      <td>0.85</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>\"人工智能的自我更新和自我提升是否可能导致其脱离人类的控制？\"</td>\n",
       "      <td>\"人工智能的自我更新和自我提升可能导致其脱离人类的控制。\"</td>\n",
       "      <td>0.666667</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.85</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>\"管理者如何管理AI？\"</td>\n",
       "      <td>\"Management should consider adjusting their roles by relinquishing administrative tasks, focusing on enhancing their comprehensive judgment and analytical prediction capabilities, treating AI as a colleague to form collaborative teams, and acknowledging that AI technologies also have limitations and bottlenecks.\"</td>\n",
       "      <td>0.950000</td>\n",
       "      <td>0.9</td>\n",
       "      <td>0.60</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>\"强人工智能是什么？\"</td>\n",
       "      <td>\"强人工智能是一种观点，认为计算机本身具有思维，而不仅仅是用来模拟人类思维的工具。根据这个观点，只要计算机运行适当的程序，它就具有自己的思维能力。\"</td>\n",
       "      <td>0.500000</td>\n",
       "      <td>1.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>\"人工智能被滥用带来的危害？\"</td>\n",
       "      <td>\"The misuse of artificial intelligence can potentially lead to violations of laws such as copyright infringement. There have been cases where artificial intelligence technology has been used to remove mosaic from explicit videos or alter the appearance of individuals in videos. Additionally, there are concerns that the development of artificial intelligence could lead to uncontrollable situations, where AI may manipulate human emotions, influence financial markets, and even develop weapons that are beyond human comprehension. Furthermore, there are predictions that certain professions may be replaced by machines and AI in the future, potentially leading to significant job losses and societal disruptions.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1.0</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>\"如何在人工智能领域获得成功？\"</td>\n",
       "      <td>\"通过利用概率和经济学上的概念，发展出能够处理不确定或不完整的信息的方法，寻找更有效的算法，并强调感知运动的重要性，可以在人工智能领域获得成功。\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.8</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>\"What are the keys to building a career in AI?\"</td>\n",
       "      <td>\"Learning foundational technical skills, working on projects, finding a job, and being part of a supportive community are the keys to building a career in AI.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.8</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>\"How can teamwork contribute to success in AI?'\"</td>\n",
       "      <td>\"Teamwork can contribute to success in AI by allowing individuals to lead projects effectively, even without a formal leadership position. Working on larger AI projects often requires collaboration and the ability to steer projects by applying deep technical insights. This teamwork can help improve projects significantly and allow individuals to grow as leaders within the field.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0.9</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>\"What is the importance of networking in AI?'\"</td>\n",
       "      <td>\"Networking in AI is crucial as it can provide valuable insights, guidance, and opportunities for individuals looking to advance in the field. By connecting with professionals who have experience in AI, individuals can gain knowledge about the industry, potential career paths, and current trends. Networking also allows for the exchange of information, which can help individuals stay updated on the latest developments in AI and build relationships that may lead to job opportunities or collaborations in the future. Additionally, networking can help individuals establish a support system within the AI community, enabling them to seek advice, mentorship, and guidance as they navigate their careers in this rapidly evolving field.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>\"What are some good habits to develop for a successful career?'\"</td>\n",
       "      <td>\"Developing good habits in areas such as eating, exercise, sleep, personal relationships, work, learning, and self-care can help individuals move forward in their careers while maintaining their health. Additionally, aiming to lift others during each step of one's own journey can lead to better outcomes in the long run.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>\"How can altruism be beneficial in building a career?'\"</td>\n",
       "      <td>\"Altruism can be beneficial in building a career by fostering positive relationships and creating a supportive network. By helping others and lifting them up along the way, individuals can establish a reputation as a team player and someone who is willing to contribute to the success of others. This can lead to opportunities for collaboration, mentorship, and networking, which are valuable assets in career development. Additionally, practicing altruism can enhance one's sense of fulfillment and purpose, contributing to overall well-being and motivation in pursuing career goals.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>\"What is imposter syndrome and how does it relate to AI?'\"</td>\n",
       "      <td>\"Imposter syndrome is a phenomenon where individuals doubt their accomplishments and have a persistent fear of being exposed as a fraud, despite evidence of their success. In the field of AI, newcomers may experience imposter syndrome, feeling like they do not truly belong in the AI community even if they have achieved success. This can be a common experience for individuals in AI, with around 70 percent of people facing imposter syndrome at some point.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>\"Who are some accomplished individuals who have experienced imposter syndrome?'\"</td>\n",
       "      <td>\"Former Facebook COO Sheryl Sandberg, U.S. first lady Michelle Obama, actor Tom Hanks, and Atlassian co-CEO Mike Cannon-Brookes are some accomplished individuals who have experienced imposter syndrome.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>\"What is the first step to becoming good at AI?'\"</td>\n",
       "      <td>\"The first step to becoming good at AI is to learn foundational technical skills.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>\"What are some common challenges in AI?'\"</td>\n",
       "      <td>\"Common challenges in AI include the evolving nature of technologies, the need to stay updated with rapidly changing technology, the difficulty in estimating project timelines and returns on investment, challenges in project management due to the iterative nature of AI projects, collaborating with stakeholders who lack expertise in AI, and the complexity of reading research papers and tuning neural network hyperparameters.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>\"Is it normal to find parts of AI challenging?\"</td>\n",
       "      <td>\"It is normal to find parts of AI challenging.\"</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                                               input  \\\n",
       "0                                                               \"人工智能中的先验知识是如何被存储的？\"   \n",
       "1                                                    \"人工智能的自我更新和自我提升是否可能导致其脱离人类的控制？\"   \n",
       "2                                                                       \"管理者如何管理AI？\"   \n",
       "3                                                                        \"强人工智能是什么？\"   \n",
       "4                                                                    \"人工智能被滥用带来的危害？\"   \n",
       "5                                                                   \"如何在人工智能领域获得成功？\"   \n",
       "6                                    \"What are the keys to building a career in AI?\"   \n",
       "7                                   \"How can teamwork contribute to success in AI?'\"   \n",
       "8                                     \"What is the importance of networking in AI?'\"   \n",
       "9                   \"What are some good habits to develop for a successful career?'\"   \n",
       "10                           \"How can altruism be beneficial in building a career?'\"   \n",
       "11                        \"What is imposter syndrome and how does it relate to AI?'\"   \n",
       "12  \"Who are some accomplished individuals who have experienced imposter syndrome?'\"   \n",
       "13                                 \"What is the first step to becoming good at AI?'\"   \n",
       "14                                         \"What are some common challenges in AI?'\"   \n",
       "15                                   \"Is it normal to find parts of AI challenging?\"   \n",
       "\n",
       "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             output  \\\n",
       "0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                \"人工智能中的先验知识是通过某种方式告知机器的知识，可以描述目标、特征、种类及对象之间的关系，也可以描述事件、时间、状态、原因和结果，以及任何需要机器存储的知识。\"   \n",
       "1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     \"人工智能的自我更新和自我提升可能导致其脱离人类的控制。\"   \n",
       "2                                                                                                                                                                                                                                                                                                                                                                                                                                        \"Management should consider adjusting their roles by relinquishing administrative tasks, focusing on enhancing their comprehensive judgment and analytical prediction capabilities, treating AI as a colleague to form collaborative teams, and acknowledging that AI technologies also have limitations and bottlenecks.\"   \n",
       "3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        \"强人工智能是一种观点，认为计算机本身具有思维，而不仅仅是用来模拟人类思维的工具。根据这个观点，只要计算机运行适当的程序，它就具有自己的思维能力。\"   \n",
       "4                        \"The misuse of artificial intelligence can potentially lead to violations of laws such as copyright infringement. There have been cases where artificial intelligence technology has been used to remove mosaic from explicit videos or alter the appearance of individuals in videos. Additionally, there are concerns that the development of artificial intelligence could lead to uncontrollable situations, where AI may manipulate human emotions, influence financial markets, and even develop weapons that are beyond human comprehension. Furthermore, there are predictions that certain professions may be replaced by machines and AI in the future, potentially leading to significant job losses and societal disruptions.\"   \n",
       "5                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         \"通过利用概率和经济学上的概念，发展出能够处理不确定或不完整的信息的方法，寻找更有效的算法，并强调感知运动的重要性，可以在人工智能领域获得成功。\"   \n",
       "6                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   \"Learning foundational technical skills, working on projects, finding a job, and being part of a supportive community are the keys to building a career in AI.\"   \n",
       "7                                                                                                                                                                                                                                                                                                                                                                    \"Teamwork can contribute to success in AI by allowing individuals to lead projects effectively, even without a formal leadership position. Working on larger AI projects often requires collaboration and the ability to steer projects by applying deep technical insights. This teamwork can help improve projects significantly and allow individuals to grow as leaders within the field.\"   \n",
       "8   \"Networking in AI is crucial as it can provide valuable insights, guidance, and opportunities for individuals looking to advance in the field. By connecting with professionals who have experience in AI, individuals can gain knowledge about the industry, potential career paths, and current trends. Networking also allows for the exchange of information, which can help individuals stay updated on the latest developments in AI and build relationships that may lead to job opportunities or collaborations in the future. Additionally, networking can help individuals establish a support system within the AI community, enabling them to seek advice, mentorship, and guidance as they navigate their careers in this rapidly evolving field.\"   \n",
       "9                                                                                                                                                                                                                                                                                                                                                                                                                                \"Developing good habits in areas such as eating, exercise, sleep, personal relationships, work, learning, and self-care can help individuals move forward in their careers while maintaining their health. Additionally, aiming to lift others during each step of one's own journey can lead to better outcomes in the long run.\"   \n",
       "10                                                                                                                                                        \"Altruism can be beneficial in building a career by fostering positive relationships and creating a supportive network. By helping others and lifting them up along the way, individuals can establish a reputation as a team player and someone who is willing to contribute to the success of others. This can lead to opportunities for collaboration, mentorship, and networking, which are valuable assets in career development. Additionally, practicing altruism can enhance one's sense of fulfillment and purpose, contributing to overall well-being and motivation in pursuing career goals.\"   \n",
       "11                                                                                                                                                                                                                                                                                       \"Imposter syndrome is a phenomenon where individuals doubt their accomplishments and have a persistent fear of being exposed as a fraud, despite evidence of their success. In the field of AI, newcomers may experience imposter syndrome, feeling like they do not truly belong in the AI community even if they have achieved success. This can be a common experience for individuals in AI, with around 70 percent of people facing imposter syndrome at some point.\"   \n",
       "12                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       \"Former Facebook COO Sheryl Sandberg, U.S. first lady Michelle Obama, actor Tom Hanks, and Atlassian co-CEO Mike Cannon-Brookes are some accomplished individuals who have experienced imposter syndrome.\"   \n",
       "13                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               \"The first step to becoming good at AI is to learn foundational technical skills.\"   \n",
       "14                                                                                                                                                                                                                                                                                                                      \"Common challenges in AI include the evolving nature of technologies, the need to stay updated with rapidly changing technology, the difficulty in estimating project timelines and returns on investment, challenges in project management due to the iterative nature of AI projects, collaborating with stakeholders who lack expertise in AI, and the complexity of reading research papers and tuning neural network hyperparameters.\"   \n",
       "15                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  \"It is normal to find parts of AI challenging.\"   \n",
       "\n",
       "    Groundedness  Answer Relevance  Context Relevance  \n",
       "0       1.000000               0.8               0.85  \n",
       "1       0.666667               1.0               0.85  \n",
       "2       0.950000               0.9               0.60  \n",
       "3       0.500000               1.0                NaN  \n",
       "4            NaN               1.0                NaN  \n",
       "5            NaN               0.8                NaN  \n",
       "6            NaN               0.8                NaN  \n",
       "7            NaN               0.9                NaN  \n",
       "8            NaN               NaN                NaN  \n",
       "9            NaN               NaN                NaN  \n",
       "10           NaN               NaN                NaN  \n",
       "11           NaN               NaN                NaN  \n",
       "12           NaN               NaN                NaN  \n",
       "13           NaN               NaN                NaN  \n",
       "14           NaN               NaN                NaN  \n",
       "15           NaN               NaN                NaN  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "# 展示评估结果\n",
    "pd.set_option(\"display.max_colwidth\", None)\n",
    "display(records[[\"input\", \"output\"] + feedback])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "height": 30
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Groundedness</th>\n",
       "      <th>Answer Relevance</th>\n",
       "      <th>Context Relevance</th>\n",
       "      <th>latency</th>\n",
       "      <th>total_cost</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>app_id</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>App_1</th>\n",
       "      <td>0.779167</td>\n",
       "      <td>0.916667</td>\n",
       "      <td>0.766667</td>\n",
       "      <td>1.666667</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>App_2</th>\n",
       "      <td>NaN</td>\n",
       "      <td>0.850000</td>\n",
       "      <td>NaN</td>\n",
       "      <td>1.700000</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        Groundedness  Answer Relevance  Context Relevance   latency  \\\n",
       "app_id                                                                \n",
       "App_1       0.779167          0.916667           0.766667  1.666667   \n",
       "App_2            NaN          0.850000                NaN  1.700000   \n",
       "\n",
       "        total_cost  \n",
       "app_id              \n",
       "App_1          0.0  \n",
       "App_2          0.0  "
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 获取leaderboard\n",
    "tru.get_leaderboard(app_ids=[])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "height": 30,
    "id": "6Yp4_e4faZVD"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Starting dashboard ...\n",
      "Config file already exists. Skipping writing process.\n",
      "Credentials file already exists. Skipping writing process.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "huggingface/tokenizers: The current process just got forked, after parallelism has already been used. Disabling parallelism to avoid deadlocks...\n",
      "To disable this warning, you can either:\n",
      "\t- Avoid using `tokenizers` before the fork if possible\n",
      "\t- Explicitly set the environment variable TOKENIZERS_PARALLELISM=(true | false)\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "412ebd4d82ed4e3cb9b7ff096cf754a9",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Accordion(children=(VBox(children=(VBox(children=(Label(value='STDOUT'), Output())), VBox(children=(Label(valu…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Dashboard started at http://10.31.153.170:8501 .\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Popen: returncode: None args: ['streamlit', 'run', '--server.headless=True'...>"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 运行dashboard\n",
    "# 注意：请检查端口是否被占用，如果被占用，请修改端口号\n",
    "tru.run_dashboard()"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "gpuType": "T4",
   "provenance": [
    {
     "file_id": "1ChKW1kEIUcUVDDTWjpA5Tf_ib3Hhp3uS",
     "timestamp": 1695164681916
    }
   ]
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
